home *** CD-ROM | disk | FTP | other *** search
/ Libris Britannia 4 / science library(b).zip / science library(b) / DJGPP / DJLSR111.ZIP / libsrc / c / io / findiop.c < prev    next >
C/C++ Source or Header  |  1993-09-26  |  3KB  |  150 lines

  1. /* This is file FINDIOP.C */
  2. /* This file may have been modified by DJ Delorie (Jan 1991).  If so,
  3. ** these modifications are Coyright (C) 1993 DJ Delorie, 24 Kirsten Ave,
  4. ** Rochester NH, 03867-2954, USA.
  5. */
  6.  
  7. /*
  8.  * Copyright (c) 1983, 1985 Regents of the University of California.
  9.  * All rights reserved.  The Berkeley software License Agreement
  10.  * specifies the terms and conditions for redistribution.
  11.  */
  12.  
  13. #if defined(LIBC_SCCS) && !defined(lint)
  14. static char sccsid[] = "@(#)findiop.c    5.7 (Berkeley) 9/22/88";
  15. #endif LIBC_SCCS and not lint
  16.  
  17. #include <stdio.h>
  18. #include <errno.h>
  19. #include <fcntl.h>
  20.  
  21. extern int errno;
  22.  
  23. #define active(iop)    ((iop)->_flag & (_IOREAD|_IOWRT|_IORW))
  24.  
  25. #define NSTATIC    20    /* stdin + stdout + stderr + the usual */
  26.  
  27. FILE _iob[NSTATIC] = {
  28.     { 0, NULL, NULL, 0, _IOREAD|_IOTEXT,    0 },    /* stdin  */
  29.     { 0, NULL, NULL, 0, _IOWRT|_IOTEXT,    1 },    /* stdout */
  30.     { 0, NULL, NULL, 0, _IOWRT|_IONBF|_IOTEXT,2 },    /* stderr */
  31.     { 0, NULL, NULL, 0, _IOWRT|_IONBF,3 },        /* stdaux */
  32.     { 0, NULL, NULL, 0, _IOWRT|_IONBF,4 },        /* stdprn */
  33. };
  34.  
  35. extern    void    *calloc();
  36.  
  37. static    char sbuf[NSTATIC];
  38. char    *_smallbuf = sbuf;
  39. static    FILE    **iobglue;
  40. static    FILE    **endglue;
  41.  
  42. static _f_morefiles();
  43.  
  44. int setmode(int handle, int newmode)
  45. {
  46.   FILE *f, **fp;
  47.   int i;
  48.   for (i=0; i<NSTATIC; i++)
  49.     if (_iob[i]._file == handle)
  50.     {
  51.       f = _iob + i;
  52.       goto got_it;
  53.     }
  54.   if (!iobglue)
  55.     goto not_got_it;
  56.   for (fp=iobglue; fp<endglue; fp++)
  57.     if ((*fp)->_file == handle)
  58.     {
  59.       f = *fp;
  60.       break;
  61.     }
  62.  
  63. got_it:
  64.   if (newmode & O_BINARY)
  65.     f->_flag &= ~_IOTEXT;
  66.   else
  67.     f->_flag |= _IOTEXT;
  68.  
  69. not_got_it:
  70.   return _setmode(handle, newmode);
  71. }
  72.  
  73. /*
  74.  * Find a free FILE for fopen et al.
  75.  * We have a fixed static array of entries, and in addition
  76.  * may allocate additional entries dynamically, up to the kernel
  77.  * limit on the number of open files.
  78.  * At first just check for a free slot in the fixed static array.
  79.  * If none are available, then we allocate a structure to glue together
  80.  * the old and new FILE entries, which are then no longer contiguous.
  81.  */
  82. FILE *
  83. _findiop()
  84. {
  85.     register FILE **iov, *iop;
  86.     register FILE *fp;
  87.  
  88.     if (iobglue == 0) {
  89.         for (iop = _iob; iop < _iob + NSTATIC; iop++)
  90.             if (!active(iop))
  91.                 return (iop);
  92.  
  93.         if (_f_morefiles() == 0) {
  94.             errno = ENOMEM;
  95.             return (NULL);
  96.         }
  97.     }
  98.  
  99.     iov = iobglue;
  100.     while (*iov != NULL && active(*iov))
  101.         if (++iov >= endglue) {
  102.             errno = EMFILE;
  103.             return (NULL);
  104.         }
  105.  
  106.     if (*iov == NULL)
  107.         *iov = (FILE *)calloc(1, sizeof **iov);
  108.  
  109.     return (*iov);
  110. }
  111.  
  112. _f_morefiles()
  113. {
  114.     register FILE **iov;
  115.     register FILE *fp;
  116.     register char *cp;
  117.     int nfiles;
  118.  
  119.     nfiles = getdtablesize();
  120.  
  121.     iobglue = (FILE **)calloc(nfiles, sizeof *iobglue);
  122.     if (iobglue == NULL)
  123.         return (0);
  124.  
  125.     endglue = iobglue + nfiles;
  126.  
  127.     for (fp = _iob, iov = iobglue; fp < &_iob[NSTATIC]; /* void */)
  128.         *iov++ = fp++;
  129.  
  130.     _smallbuf = calloc(nfiles, sizeof(*_smallbuf));
  131.     return (1);
  132. }
  133.  
  134. _fwalk(function)
  135.     register int (*function)();
  136. {
  137.     register FILE **iov;
  138.     register FILE *fp;
  139.  
  140.     if (iobglue == NULL) {
  141.         for (fp = _iob; fp < &_iob[NSTATIC]; fp++)
  142.             if (active(fp))
  143.                 (*function)(fp);
  144.     } else {
  145.         for (iov = iobglue; iov < endglue; iov++)
  146.             if (*iov && active(*iov))
  147.                 (*function)(*iov);
  148.     }
  149. }
  150.